/**
 * Copyright (C) 2011 - @le.nguyen
 * @Created Jul 30, 2011
 *
 * TODO
 */
package com.conan.app.dailyflickr.app;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import com.conan.app.dailyflickr.AppData;
import com.conan.app.dailyflickr.provider.Constants;

import android.app.WallpaperManager;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;

/**  */
public class ApplicationUtils {
    private static final String TAG = "ApplicationUtils";

    public static boolean checkInternetConnection(Context context){
        ConnectivityManager connMan = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        return (connMan.getActiveNetworkInfo() != null 
                && connMan.getActiveNetworkInfo().isConnected());
    }

    public static String buildDateString(Date date){
        SimpleDateFormat formatter = new SimpleDateFormat("d MMM yyyy");

        return formatter.format(date.getTime());	
    }
    /******************************************************************************/
    /*************************		download file 		***************************/
    /******************************************************************************/

    private static final String OWN_DIR = "daily";
    private static final String OWN_FILE = "daily_data";



    public static Bitmap getBitmapFile(Context context, final String name){	
        /**  /mnt/sdcard/Android/data/packages_name/files */
        File files = context.getExternalFilesDir(null);

        if(files != null){
            File image = new File(files, name);
            if(image.exists()){
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                try {
                    Bitmap bm = BitmapFactory.decodeFile(image.getAbsolutePath(), options);

                    if(bm != null) return bm;	
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }				
            }
        }

        return null;
    }

    public static void storeBitmapFile(Context context, String filename, Bitmap bitmap){
        /**  /mnt/sdcard/Android/data/packages_name/files */
        File image = new File(context.getExternalFilesDir(null), filename);
        if(Constants.LOG){
            Log.d(Constants.TAG, String.format("[image_path] %s", image.getAbsolutePath() ));
        }
        if(image.exists()){
            image.delete();
        }

        FileOutputStream fOut = null;

        try{
            // fOut = context.openFileOutput(filename, context.MODE_PRIVATE);
            fOut = new FileOutputStream(image.getAbsolutePath());
            // outStrWriter = new OutputStreamWriter(fOut);			
            bitmap.compress(Bitmap.CompressFormat.JPEG, 95, fOut);
            // outStrWriter..write(data);
            fOut.flush();
        }catch (OutOfMemoryError e) {
            e.printStackTrace();
        }catch (Exception e) { 
            e.printStackTrace();
        }

        finally {
            try {
                // if(outStrWriter != null) outStrWriter.close();
                if(fOut != null)  fOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static boolean saveFile(Context context, JSONObject object){		
        if(object != null){
            FileOutputStream fos;
            try {
                fos = context.openFileOutput(OWN_FILE, Context.MODE_PRIVATE);
                fos.write(object.toString().getBytes());
                fos.close();
                return true;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }			
        }
        return false;
    }

    public static void deleteFile(Context context, String filename){	
        // File file = context.getFilesDir();
        File file = context.getExternalFilesDir(null);
        /**  /mnt/sdcard/Android/data/packages_name/files */
        if(file != null){
            File image = new File(file, filename);
            if(image.exists()){
                image.delete();
            }
        }
    }

    public static void deleteFiles(Context context, final String patternName){	
        // File files = context.getFilesDir();
        /**  /mnt/sdcard/Android/data/packages_name/files */
        File files = context.getExternalFilesDir(null);

        String[] names =  files.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String filename) {
                if(!TextUtils.isEmpty(patternName) &&
                        filename.contains(patternName)) return true;
                return false;
            }
        });

        if(names != null && names.length > 0){
            for(String name: names){
                File image = new File(files, name);
                if(image.exists()){
                    image.delete();
                }
            }
        }

    }

    public static JSONObject getDataFromFile(Context context) {
        StringBuffer buffer = new StringBuffer();
        FileInputStream fIn = null;
        InputStreamReader isr = null;
        try{
            /* We have to use the openFileInput()
             * method the ActivityContext provides.
             * Again for security reasons with openFileInput(...) */
            fIn = context.openFileInput(OWN_FILE);
            isr = new InputStreamReader(fIn);
            /* Prepare a char-Array that will
             * hold the chars we read back in. */
            char[] inputBuffer = new char[1024];
            if(isr.read(inputBuffer) > 0 ){
                buffer.append(inputBuffer);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if(fIn != null){
                    fIn.close();
                }
                if(isr != null){
                    isr.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        try {
            return buffer.length() > 0? new JSONObject(buffer.toString()):null;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    /*************** DOWNLOAD FILE **************************/
    private static InputStream fetch(String urlString) throws MalformedURLException, IOException{
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }

    public static boolean downloadBitmap(Context context, String urlString, String title, boolean isWallpaper){
        // replace small to large
        String pattern = "_m.jpg";
        String newPattern = "_b.jpg";

        urlString = urlString.replaceAll(pattern, newPattern);
        InputStream is;
        try {
            is = fetch(urlString);
        } catch (MalformedURLException e) {			
            e.printStackTrace();
            return false;
        } catch (IOException e) {			
            e.printStackTrace();
            return false;
        }
        // TODO: save to sdcard later
        //saveToSdcard();
        try{
            Bitmap bitmap = BitmapFactory.decodeStream(is);

            if(bitmap == null) return false;

            if(isWallpaper){
                try {
                    WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
                    wallpaperManager.setBitmap(bitmap);
                } catch (IOException e) {				
                    e.printStackTrace();
                    return false;
                }

            }else{
                String name = urlString.substring(urlString.lastIndexOf("/"));
                saveToSDCard(context, bitmap, name, title);
            }

            return true;
        }catch (OutOfMemoryError e) {
            e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
        return false;
    }

    private static void saveToSDCard(Context context, Bitmap bitmap, String name, String title) {
        boolean mExternalStorageAvailable = false;
        boolean mExternalStorageWriteable = false;
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            mExternalStorageAvailable = mExternalStorageWriteable = true;
            Log.v(TAG, "SD Card is available for read and write "
                    + mExternalStorageAvailable + mExternalStorageWriteable);
            saveFile(context, bitmap, name, title);
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            mExternalStorageAvailable = true;
            mExternalStorageWriteable = false;
            Log.v(TAG, "SD Card is available for read "
                    + mExternalStorageAvailable);
        } else {
            mExternalStorageAvailable = mExternalStorageWriteable = false;
            Log.v(TAG, "Please insert a SD Card to save your Video "
                    + mExternalStorageAvailable + mExternalStorageWriteable);
        }
    }

    private static void saveFile(Context context, Bitmap bitmap, String fullname, String title) {
        ContentValues values = new ContentValues();
        File SDCardRoot = Environment.getExternalStorageDirectory();
        File SDCardDownload = new File(SDCardRoot.getAbsolutePath().concat(AppData.DOWNLOAD_FOLDER));


        File outputFile = new File(SDCardDownload, fullname);
        values.put(MediaStore.MediaColumns.DATA, outputFile.toString());
        // values.put(MediaStore.MediaColumns.TITLE, title);
        values.put(MediaStore.MediaColumns.DATE_ADDED, System
                .currentTimeMillis());
        values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
        Uri uri = context.getContentResolver().insert(
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                values);;

                try {
                    OutputStream outStream = context.getContentResolver()
                            .openOutputStream(uri);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 95, outStream);

                    outStream.flush();
                    outStream.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                bitmap.recycle();
                bitmap = null;
    }

}
